package cn.com.dingtek.genius.manager.server.service;

import cn.com.dingtek.genius.manager.server.repository.db.entity.AuthGroup;
import cn.com.dingtek.genius.manager.server.repository.db.entity.AuthGroupRule;
import cn.com.dingtek.genius.manager.server.repository.db.entity.UserBase;
import cn.com.dingtek.genius.manager.server.repository.db.manager.AuthGroupManager;
import cn.com.dingtek.genius.manager.server.repository.db.manager.AuthGroupRuleManager;
import cn.com.dingtek.genius.manager.server.repository.db.manager.UserBaseManager;
import cn.com.dingtek.genius.manager.server.utils.MybatisPlusUtil;
import cn.com.dingtek.genius.manager.server.utils.Verify;
import cn.com.dingtek.genius.manager.server.utils.VerifyException;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class AuthGroupService {
    @Autowired
    private AuthGroupManager authGroupManager;

    @Autowired
    private UserBaseManager userBaseManager;
    @Autowired
    private AuthGroupRuleManager authGroupRuleManager;

    public IPage<AuthGroup> list(AuthGroup param, int currentPage, int pageSize) {
        QueryWrapper<AuthGroup> query = Wrappers.emptyWrapper();
        if (param != null) {
            query = MybatisPlusUtil.customLikeQuery(null, "group_name", param.getGroupName());
        }

        return authGroupManager.page(new Page<AuthGroup>(currentPage, pageSize).setAsc("id"), query);
    }


    public void add(AuthGroup param, Date now) {
        try {
            Verify.isTrue(authGroupManager.save(AuthGroup.builder()
                    .groupName(param.getGroupName())
                    .upLock(param.getUpLock())
                    .remark(param.getRemark())
                    .ctime(now)
                    .utime(now)
                    .version(0L)
                    .build()), "新增角色失败。");
        } catch (DuplicateKeyException e) {
            throw new VerifyException("该角色名已存在。");
        }
    }

    public AuthGroup info(Long id) {
        Verify.isTrue(id != null && id > 0, "角色不存在");
        return authGroupManager.getById(id);
    }

    public void update(AuthGroup param, Date now) {
        Verify.isTrue(param.getId() != null && param.getId() > 0, "角色不存在");

        AuthGroup authGroup = authGroupManager.getById(param.getId());
        Verify.notNull(authGroup, "角色不存在");

        AuthGroup toUpdate = AuthGroup.builder()
                .id(param.getId())
                .groupName(param.getGroupName())
                .upLock(param.getUpLock())
                .remark(param.getRemark())
                .utime(now)
                .version(authGroup.getVersion()).build();

        Verify.isTrue(authGroupManager.updateById(toUpdate), "更新角色失败");
    }

    public void remove(Long id) {
        if (id != null && id > 0) {
            long count = userBaseManager.count(Wrappers.<UserBase>query().eq("auth_group_id", id));
            Verify.isTrue(count > 0, "角色被使用，不能删除。");
            authGroupManager.removeById(id);
        }
    }

    public void grant(AuthGroupRule param, Date now) {
        Verify.isTrue(param.getGroupId() != null && param.getGroupId() > 0, "角色不存在");
        Verify.isTrue(param.getRuleId() != null && param.getRuleId() > 0, "权限不存在");

        AuthGroupRule authGroupRule = authGroupRuleManager.getAuthGroupRule(param.getGroupId(), param.getRuleId());
        if (authGroupRule != null) {
            return;
        }

        authGroupRuleManager.save(AuthGroupRule.builder()
                .groupId(param.getGroupId())
                .ruleId(param.getRuleId())
                .ctime(now)
                .build());
    }

    public void unGrant(AuthGroupRule param, Date now) {
        Verify.isTrue(param.getGroupId() != null && param.getGroupId() > 0, "角色不存在");
        Verify.isTrue(param.getRuleId() != null && param.getRuleId() > 0, "权限不存在");

        AuthGroupRule authGroupRule = authGroupRuleManager.getAuthGroupRule(param.getGroupId(), param.getRuleId());
        if (authGroupRule == null) {
            return;
        }

        authGroupRuleManager.removeById(authGroupRule.getId());
    }

    public List<JSONObject> options() {
        List<AuthGroup> authGroups = authGroupManager.list();
        return authGroups.stream()
                .map(item -> new JSONObject()
                        .fluentPut("id", item.getId())
                        .fluentPut("groupName", item.getGroupName()))
                .collect(Collectors.toList());
    }
}
